package org.goodsl.deploymap

/**
 * Created with IntelliJ IDEA.
 * User: Simon Xiao
 * Date: 12-12-19
 * Time: 上午9:58
 * Copyright goodsl.org 2012~2020
 */

enum ServiceType {
    web,
    damon,
    unknow
}

enum ServiceRelationType {
    PullFrom,
    PushTo
}
class Service extends SysElement{

    ServiceType type
    boolean isPublicAccess = false
    boolean isIntroduced = false
    boolean isDatabase = false


    ArrayList<ServiceRelation> relations = new ArrayList<ServiceRelation>()

    ArrayList<ServiceUseModule> modules = new ArrayList<ServiceUseModule>()

    UseModuleDelegate useModuleDelegate

    @Override
    int hashCode(){
        return name.hashCode()
    }

    void modules(Closure cl){
        if(useModuleDelegate == null)
            useModuleDelegate  = new UseModuleDelegate(service: this)
        cl.delegate = useModuleDelegate
        cl.resolveStrategy = Closure.DELEGATE_FIRST
        cl()
    }

    void pullfrom(Closure cl){
        ServiceRelation delegate = new ServiceRelation(
                service: this,
                relationType:ServiceRelationType.PullFrom)
        cl.delegate = delegate
        cl.resolveStrategy = Closure.DELEGATE_FIRST
        cl()
    }

    void pushto(Closure cl){

        ServiceRelation delegate = new ServiceRelation(
                service: this,
                relationType:ServiceRelationType.PushTo)
        cl.delegate = delegate
        cl.resolveStrategy = Closure.DELEGATE_FIRST
        cl()

    }



    void publicAccess(boolean isPublicAccess ){
        this.isPublicAccess = isPublicAccess
    }
    void introduced(boolean isIntroduced){
        this.isIntroduced = isIntroduced
    }

    void database(boolean isDatabase){
        this.isDatabase = isDatabase
    }
    void type(String theType){
        String typeStr = theType.toLowerCase()
        if (typeStr == "web"){
            this.type = ServiceType.web
        }else if (theType == "damon") {
            this.type = ServiceType.damon
        }else
            this.type = ServiceType.unknow
    }

    def propertyMissing(String name){
        if (name == "publicAccess")
            this.isPublicAccess = true
        else if (name == "isIntroduced")
            this.isIntroduced = true
        else if (name == "database")
            this.isDatabase = true
    }

    class UseModuleDelegate{

        Service service

        def methodMissing(String methodName,args){
            String description = ""
            if (args!=null)
                description = args[0].toString()
            ServiceUseModule useModule = new ServiceUseModule(
                    serviceName: service.name,
                    moduleName: methodName,
                    desc: description,
                    system: service.system
            )
            service.modules.add(useModule)
        }

        def propertyMissing(String methodName){
            ServiceUseModule useModule = new ServiceUseModule(
                    serviceName: service.name,
                    moduleName: methodName,
                    system: service.system
            )
            service.modules.add(useModule)
        }

    }

}

class ServiceRelation{
    AppSystem system
    String nameA
    String nameB
    ServiceRelationType relationType
    String desc =""

    public Service getServiceA(){
        return  system.getService(nameA)
    }
    public Service getServiceB(){
        return  system.getService(nameB)

    }
    Service service

    def methodMissing(String methodName,args){
        String description = relationType== ServiceRelationType.PullFrom?"pull from":"push to"
        if (args!=null)
            description = args[0].toString()

        ServiceRelation relation = new ServiceRelation(
                system: service.system,
                nameA: service.name,
                nameB: methodName,
                relationType: this.relationType,
                desc:description
        )
        service.relations.add(relation);
    }

    def propertyMissing(String methodName){
        String description = relationType== ServiceRelationType.PullFrom?"pull from":"push to"
        ServiceRelation relation = new ServiceRelation(
                system: service.system,
                nameA: service.name,
                nameB: methodName,
                relationType: this.relationType,
                desc:description
        )
        service.relations.add(relation);
    }


}

class ServiceUseModule{
    AppSystem system
    String serviceName
    String moduleName
    String desc = ""
    public Service getService(){
        return  system.getService(serviceName)
    }

    public Module getModule(){
        return  system.getModule(moduleName)
    }



}